package com.yk._16理解CAS;


import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicStampedReference;

public class _02ABA问题 {


    /**
     * 线程  期望  修改     版本   备注
     * 线程A 2020           1       A线程启动
     * 线程B 2020           1       B线程启动
     * 线程A 2020 ->2021    2       A线程修改第一次,从2020修改成了2021
     * 线程A 2021 ->2020    3       A线程修改第二次,把2021修改回来了2020
     * 线程B 2020 ->2021    -      修改失败.虽然都是2020,但是Stampe不同,版本号不同
     * @auther yk
     *
     */
    public static void main(String[] args) {

        AtomicStampedReference<String> atomicStampedReference = new AtomicStampedReference<>("2020", 1);

        new Thread(()->{
            //获取版本号并输出
            System.out.println(Thread.currentThread().getName() + atomicStampedReference.getStamp());
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            atomicStampedReference.compareAndSet("2020",
                    "2021",
                    atomicStampedReference.getStamp(),
                    atomicStampedReference.getStamp()+1);
            //获取版本号并输出
            System.err.println(Thread.currentThread().getName() + atomicStampedReference.getStamp());

            atomicStampedReference.compareAndSet("2021",
                    "2020",
                    atomicStampedReference.getStamp(),
                    atomicStampedReference.getStamp()+1);
            //获取版本号并输出
            System.out.println(Thread.currentThread().getName() + atomicStampedReference.getStamp());
        },"线程A-").start();

        new Thread(()->{
            //获取版本号并输出
            int stamp = atomicStampedReference.getStamp();
            System.out.println(Thread.currentThread().getName() + String.valueOf(stamp));
            try {
                TimeUnit.SECONDS.sleep(2);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            boolean b = atomicStampedReference.compareAndSet("2020",
                    "2021",
                    stamp,
                    stamp + 1);
            if (b){
                System.out.println(Thread.currentThread().getName()+"更新成功");
            }else{
                System.out.println(Thread.currentThread().getName()+"更新失败");
            }

        },"线程B-").start();
    }

}
